//: ## MARK, TODO, FIXME
import Foundation
/*
 // MARK： 类似于OC中的 #pragma mark
 // MARK： - 类似于OC中的 #pragma mark -
 // TODO： 用于标记未完成的任务
 // FIXME： 用于标记待修复的问题
 ⚠️很多时候为了更明显的提示,可以用 #warning
 实际效果截图: 当前page的Resource的"mark_img"图片
 平时写方法的时候,返回值要是没有确定好,此时想让这个方法先成功运行,可以在返回值直接写fatalError
 */
//: ## 条件编译
/*
 // 操作系统：mac0S\i0S\tvOS\watchOS\Linux\Android\Windows\FreeBSD
 #if os(macOS) || os(iOS)
 
// CPU架构：i386\×86_64\arm\arm64
 #elseif arch（×86_64） I| arch（arm64）
 
 // swifti版本
 #elseif swift(<5) && swift (>=3)
 
 // 模拟器
 #elseif targetEnvironment（simulator）
 // 可以导入某模块
 #elseif canImport(Foundation)
 #else #endif
 
 //后面的是系统自带的条件,只能放这些,满足后就可以进入对应的下面的执行语句
 */

/*
 if Debug模式(开发时)会触发的代码, else发包是会发的代码
 设置如截图: Resources里面的"Debug_img"
 
 一般作用:debug模式下的打印,Release就不打印,👉🏻截图(Resources里面的"log_img")是mj老师封装好的打印文件
 */
//: ## 系统版本检测
//一般用于: 程序运行过程中判断一下操作系统的版本,不是条件编译. 👉🏻截图(Resources里面的"version_img")
//:## API可用性说明
//用于标明该代码应该是在什么版本以上才能使用.👉🏻截图(Resources里面的"API_img")
//: ## iOS程序的入口
/*
 在AppDelegate上面默认有个@UIApplicationMain标记，这表示口编译器自动生成入口代码（main函数代码），自动设置AppDelegate为APP的代理
 也可以删掉@UIApplicationMain，自定义入口代码：新建一个main.swift文件👉🏻截图(Resources里面的"API_img")
 */
//:## dynamic
//被 @objc dynamic 修饰的内容会具有动态性, 比如调用方法会走runtime那套流程
//: ## KVC / KVO
/*
 Swift支持KVC / KVO 的条件
 1. 属性所在的 类 / 监听器 最终继承自NSObject
 2. 用 @objc dynamic 修饰对应的属性
 */
class Observer: NSObject {// 创建一个监听器
    //实现了监听方法
    override func observeValue(forKeyPath keyPath: String?,
                               of object: Any?,
                               change: [NSKeyValueChangeKey : Any]?,
                               context: UnsafeMutableRawPointer?) {
        
        print("observeValue", change?[.newKey] as Any)
    }
}


class Person: NSObject {
    @objc dynamic var age: Int = 0 // 用@objc dynamic修饰的属性才有多态, 就可以使用runtime使用kvokvc
    var observer: Observer = Observer() //定义一个监听器, 继承自nsobeject
    
    override init() {
        super.init()
        //penson注册的时候注册监听器
        self.addObserver(observer,
                         forKeyPath: "age",
                         options: .new,
                         context: nil)
    }
    
    deinit {
        //penson销毁的时候移除监听器
        self.removeObserver(observer,
                            forKeyPath: "age")
    }
}

var p = Person()
p.age = 20 //observeValue Optional(20)
p.setValue(25, forKey: "age") //observeValue Optional(25)
//: ## block方式的KVO
class Person1: NSObject {
    @objc dynamic var age: Int = 0
    //使用NSKeyValueObservation必须继承自NSObject
    var observation: NSKeyValueObservation? //监听器
    override init() {
        super.init()
        // 方法写法: \ + 类名.属性名  options(是枚举)
        observation = observe(\Person1.age, options: .new, changeHandler: { Person1, change in
            print(change.newValue as Any)
        })
    }
}

var p2 = Person1()
p2.age = 10//Optional(10)
p2.age = 20//Optional(20)
p2.setValue(30, forKey: "age")//Optional(30)












//: [Next](@next)
